#include "stdafx.h"
#include "VerInfo.h"
using namespace PluginICPopenCVLib;
#include "MxPluginManager\MxPluginManager1.h"
#include "ImageCuratorPluginLib.h"

#include "PluginICPopenCV.h"
#include "SumVal.h"


ImageCuratorPluginLib::ImageCuratorPluginLib(void) :
	_refCnt(0),
	_pluginMngr(nullptr),
	_iImageCurator(nullptr),
	_valid(false)
{
	bool rc = false;

	try
	{
		_pluginMngr = new MxPluginManager(); 
		if(_pluginMngr->RefreshPluginsInRootFolder(PRODID_DefaultPluginRootFolder, SID_ImageCurator) == true)
		{
			MxPluginLib * imageCuratorPlugin = nullptr;
			if ((imageCuratorPlugin = _pluginMngr->GetPlugin(PRODID_PluginImageCurator)) == nullptr)
				MX_SETERROR(MX11103, MxError::System,  MxError::Abort,  MxError::VerboseReport, "unable to find PluginImageCurator"); 
			else
			{
				if ((_iImageCurator = static_cast<IImageCurator *>(imageCuratorPlugin->CreateClassInstance(IImageCuratorIID::Guid()))) == nullptr)
					MX_SETERROR( MX11104, MxError::CodeDefect,  MxError::Abort,  MxError::VerboseReport, "unable to obtain IImageCurator for PluginImageCurator"); 
				else
				{
					if ( _iImageCurator->SetImageCuratorPluginLib(this) == false) 
						MX_SETERROR( MX11105, MxError::CodeDefect,  MxError::Abort,  MxError::VerboseReport, "SetImagePluginSpec() failed"); 
					else
					{
						if  (SetFunctionDefs(_iImageCurator) == false)
							MX_SETERROR( MX11105, MxError::CodeDefect,  MxError::Abort,  MxError::VerboseReport, "SetFunctionDefs() failed"); 
						else
						{
							if ( (Validate() == false) || (IsValid() == false))
								MX_SETERROR( MX11107, MxError::CodeDefect,  MxError::Abort,  MxError::VerboseReport, "Validate() failed"); 
							else
							{
								rc = true;
							}
						}
					}
				}
			}
		}
	}
	catch(std::exception const& e)
	{
		MX_SETERROR(MX11108, MxError::CodeDefect,  MxError::Abort,  MxError::QuietReport, "Unexpected exception: %s", e.what()); 
	}
}


ImageCuratorPluginLib::~ImageCuratorPluginLib(void)
{
	if (_iImageCurator != nullptr)
		_iImageCurator->DestroyPtr();
	_iImageCurator = nullptr;

	if (_pluginMngr != nullptr)
		delete _pluginMngr; 
	_pluginMngr = nullptr;
}

bool  MXSTDMETHOD ImageCuratorPluginLib::Validate()
{
	bool rc  = false;

	if ((_iImageCurator->Validate() == false) || (_iImageCurator->IsValid() == false))
		MX_SETERROR(MX11109, MxError::System,  MxError::Abort,  MxError::VerboseReport, "_iImageCurator->Validate() failed"); 
	else
	{
		_valid = true;
		rc = _valid;
	}
	return rc;
}

IImageCurator*	MXSTDMETHOD ImageCuratorPluginLib::GetIImageCurator()
{ 
	IImageCurator*	rc = nullptr;

	if ((_iImageCurator == nullptr) || (_iImageCurator->IsValid() == false))
		MX_SETERROR(MX11110, MxError::CodeDefect,  MxError::Abort,  MxError::QuietReport, "_iImageCurator is null or invalid"); 
	else
	{
		rc = _iImageCurator;
		rc->DuplicatePtr();
	}
	return rc; 
}

bool		MXSTDMETHOD ImageCuratorPluginLib::SetFunctionDefs(IImageCurator *iImageCurator)
{
	bool rc  = false;

	if (iImageCurator == nullptr)
		MX_SETERROR(MX11111, MxError::InvalidParams,  MxError::Abort,  MxError::VerboseReport, "iImageCurator is null");
	else
	{
		GUID Sum = MxGUID::ConvertFromString("{8D97CCEC-7DE4-46AF-A9C7-BBA4011AA6F5}");
		if (    (_iImageCurator->CreateFunctionDef(Sum, "SumVal" , "adds two values", "Utils", "Sum", 100, dynamic_cast<IImageCuratorFnCall *>(new SumVal())) == false)
			 ||	(_iImageCurator->AddFunctionParamDef( Sum, "ValA", IImageCuratorFnDef::Direction::Input, IImageCuratorFnDef::ParamType::Integer, "0", "Val A", "first param", "0", "100") == false)
			 ||	(_iImageCurator->AddFunctionParamDef( Sum, "ValB", IImageCuratorFnDef::Direction::Input, IImageCuratorFnDef::ParamType::Integer, "0", "Val B", "second param", "0") == false)
			 ||	(_iImageCurator->AddFunctionParamDef(Sum, "Result", IImageCuratorFnDef::Direction::Output, IImageCuratorFnDef::ParamType::Integer, "0", "Result sum", "sum of Val A and Val B") == false))
				MX_SETERROR(MX11112, MxError::System,  MxError::Abort,  MxError::VerboseReport, "unable to add Fn SumVal");
		else
		{
			IImageCuratorFn *iFn = nullptr;
			if((iFn = _iImageCurator->GetIImageCuratorFn(Sum)) == nullptr)
				MX_SETERROR(MX11113, MxError::System,  MxError::Abort,  MxError::VerboseReport, "cannot get IImageCuratorFn");
			else
			{
				if (   (iFn->SetParamInt("ValA", 50) == false)
					|| (iFn->SetParamInt("ValB", 150) == false)
					|| (iFn->SetParamInt("Result", 0) == false))
					MX_SETERROR(MX11114, MxError::System,  MxError::Abort,  MxError::VerboseReport, "failed to set params for SampleInvocation");
				else
				{
					rc = true;
				}
				iFn->DestroyPtr();
			}
		}
	}
	return rc;
}

long		MXSTDMETHOD ImageCuratorPluginLib::DestroyPtr(void)
{
	long cnt = InterlockedDecrement(&_refCnt);
	if ( cnt == 0 )
		delete this;
	return cnt;
}

long		MXSTDMETHOD ImageCuratorPluginLib::DuplicatePtr(void)
{
	return InterlockedIncrement(&_refCnt);
}

void *		MXSTDMETHOD ImageCuratorPluginLib::Dynamic_cast(const GUID IId)
{
	void *rc = nullptr;

	if ( MxGUID::IsEqual(IId, IMxPluginBaseIID::Guid()))
		rc = static_cast<IMxPluginBase *>(this);
	else
		rc = nullptr;

	std::string tmp;
	if (rc == nullptr)
		MX_SETERROR(MX11115, MxError::Install, MxError::Abort, MxError::QuietReport, "Dynamic_cast does not support IID=%s", MxGUID::ConvertToString(IId, &tmp));
	else
		((IMxPluginBase *)rc)->DuplicatePtr();

	return rc;
}


